#include "TS.h"
#include "KeyboardHandle.h"
#include <thread>

// 引用Windows头文件
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif // WIN32_LEAN_AND_MEAN
#include <windows.h>

#include <Core.h>

class WindowsEvent
{
public:
	WindowsEvent() : mEvent(::CreateEventW(nullptr, TRUE, FALSE, nullptr)) {}
	~WindowsEvent() { ::CloseHandle(mEvent); }
	void WaitEvent() { ::WaitForSingleObject(mEvent, INFINITE); }
	void Reset() { ::ResetEvent(mEvent); }
	void Set() { ::SetEvent(mEvent); }

private:
	HANDLE mEvent;
};

static bool ts_switch{false};
static bool w_state{false};
static bool space_state{false};
static bool ctrl_state{false};
static unsigned int proc_id{0xffffffffu};
static WindowsEvent ts_signal{};

static void TSProcess(const KeyBoardData *data)
{
	const DWORD w = data->wParam;
	INFO("<{%d}><{%d}><{%d}>", data->vkCode, data->scanCode, data->dwExtraInfo);
	if (w == WM_KEYDOWN && !space_state && data->dwExtraInfo == 0ull && data->vkCode == VK_SPACE)
	{
		INFO("<{}><{}><{}>", data->vkCode, data->scanCode, data->dwExtraInfo);
		space_state = true;
	}
	if (w == WM_KEYUP && space_state && data->dwExtraInfo == 0ull && data->vkCode == VK_SPACE)
	{
		INFO("<{}><{}><{}>", data->vkCode, data->scanCode, data->dwExtraInfo);
		space_state = false;
	}
	if (w == WM_KEYDOWN && !ctrl_state && data->dwExtraInfo == 0ull && data->vkCode == VK_LCONTROL)
	{
		INFO("<{}><{}><{}>", data->vkCode, data->scanCode, data->dwExtraInfo);
		ctrl_state = true;
	}
	if (w == WM_KEYUP && ctrl_state && data->dwExtraInfo == 0ull && data->vkCode == VK_LCONTROL)
	{
		INFO("<{}><{}><{}>", data->vkCode, data->scanCode, data->dwExtraInfo);
		ctrl_state = false;
	}
	if (w == WM_KEYDOWN && !w_state && data->dwExtraInfo == 0ull && data->vkCode == 'W')
	{
		w_state = true;
	}
	if (w == WM_KEYUP && w_state && data->dwExtraInfo == 0ull && data->vkCode == 'W')
	{
		w_state = false;
	}
	if (space_state && ctrl_state && w_state)
	{
		ts_signal.Set();
	}
}

DWORD TSMain(PVOID)
{
	using namespace std::chrono;
	while (ts_switch)
	{
		ts_signal.WaitEvent();
		while (space_state && ctrl_state && w_state)
		{
			keybd_event('W', 17, KEYEVENTF_KEYUP, 1);
			std::this_thread::sleep_for(10ms);
			keybd_event('W', 17, 0, 1);
			std::this_thread::sleep_for(10ms);
			INFO("TS...");
		}
		if (w_state)
		{
			keybd_event('W', 17, 0, 1);
		}
		else
		{
			keybd_event('W', 17, KEYEVENTF_KEYUP, 1);
		}
		ts_signal.Reset();
	}
	return 0x0;
}

void TS::Start()
{
	ts_switch = true;
	Keyboard& kd = Keyboard::GetInstance();
	kd.AddProc(TSProcess);
	DWORD tsThreadID{};
	HANDLE tsThread = CreateThread(nullptr, 0x0, TSMain, nullptr, 0x0, &tsThreadID);
}


TS::TS() {}

TS::~TS()
{
	ts_switch = false;
}

TS & TS::GetInstance(){
	static TS ins{};
	return ins;
}